package kgame5.k3d.core.parser {
import kgame5.k3d.core.math.NumberUV;
import kgame5.k3d.core.math.Vertex3D;
import kgame5.k3d.core.obj3d.info.geometry.Face3D;
import kgame5.k3d.core.obj3d.info.geometry.GeometryInfo;
import kgame5.k3d.core.obj3d.node3d.Mesh3D;

import flash.utils.Dictionary;

/*这个就是一个数据组
	# object Object01 to come ...
	#
	v  4.71292305 7.57816410 -0.01040745
	# 12 vertices
	
	vt  0.31992051 0.83834887 1.50000000
	# 30 texture vertices
	
	g Object01
	f 92/57 93/58 86/61
	# 20 faces
	
	*/
public class ObjParser {
	
	//dict[name]=mesh3D
	public var dict_mesh:Dictionary=new Dictionary();//导出的是多个模型
	
	public var firstMesh3D:Mesh3D=null;
	
	//加载成功后调用这个
	 public function parse(sSrc:String):Mesh3D {

		var aText:Array=sSrc.split(/\ng\n/);//分割成一个组一个组的
	
		var len:int=aText.length-1;//注意aText的最后一个是个长度为0，是个NaN的字符串，大概是文本结束标志吧
		
		//导出的是多个模型
		for(var i:int=0;i<len;i++){
	        var mesh:Mesh3D=readMesh3D(aText[i]);
	        dict_mesh[mesh.name]=mesh;
	        
	        if(firstMesh3D==null){//设置好第一个模型，这个就是为了照顾老程序而用的
	        	firstMesh3D=mesh;	
	        }
	        	
	        //T.p("读取一个Mesh3D成功", mesh.name);
		}
		
		return firstMesh3D;
     }
	
	//从一个数据组里读取出数据
	public function readMesh3D(sData:String):Mesh3D{
		
		//1,提取名字，简单情况下用正则表达式很好
		var rg:RegExp=/# object ([\w\d]+) to come/;
		var name:String=rg.exec(sData)[1];
		
		var aText:Array=sData.split("\n");

		//---提取自己感兴趣的3个数组
		var gi:GeometryInfo=new GeometryInfo();
		
		//var aVertex:Vector.<Vertex3D>;
		gi.aVertex=new Vector.<Vertex3D>();
		
		gi.aFace=new Vector.<Face3D>();
		
		gi.aNumberUV = new Vector.<NumberUV>();
		
		var i:int;
		var len:int;
		
		//注意一个obj里如果包含多个模型，则需要的是相对顶点索引，否则v,vt索引就是对于整个模型来说的索引了
		var textureVerticesCount:int=0;
		var verticesCount:int=0;
		
		//T.p("开始就解吸");
		len=aText.length;
		for(i=0;i<len;i++){
			//1,每一行的数据解析成数组
			var aItem:Array=aText[i].split(" ");//每个条目
			//注意这个结果是长度是5,因为v后是两个空格
			//v  -6.05815268 14.48638535 -26.09479904
			
			//2,根据行头的标号来处理
			var head:String=aItem[0];
			
			//注意这么提取顶点数也是很有讲究的,因为"texture vertices"里也有"vertices"
			//不精心处理会导致数值覆盖
			if(aText[i].indexOf("texture vertices")!=-1){
				textureVerticesCount=parseInt(aItem[1]);
				//T.p("textureVerticesCount",textureVerticesCount);
			}else {
				if(aText[i].indexOf("vertices") != -1) {
					verticesCount = parseInt(aItem[1]);
					//T.p("verticesCount", verticesCount);
				}
			}
			
			//ttt(i+"行的aItem为_"+head,aItem);
			switch(head){
				case "v":
					//T.p("这个是v!!");
					//T.p(parseInt(aItem[1])+" "+parseInt(aItem[2])+" "+parseInt(aItem[3])+" ");
					//aVB_p.push(parseFloat(aItem[2]));//转换到左手坐标,挺乱的，目的是让模型0角度为z轴
					//aVB_p.push(parseFloat(aItem[3]));
					//aVB_p.push(-parseFloat(aItem[4]));
					
					var vv:Vertex3D=new Vertex3D(0,0,0);
					vv.x=parseFloat(aItem[2]);
					vv.y=parseFloat(aItem[3]);
					vv.z=-parseFloat(aItem[4]);
					
					gi.aVertex.push(vv);
					
//					aVB_p.push(-parseFloat(aItem[2]));//转换到左手坐标,挺乱的，目的是让模型0角度为z轴
//					aVB_p.push(parseFloat(aItem[3]));
//					aVB_p.push(parseFloat(aItem[4]));
				break;
				case "vt":
					//T.p("这个是vt!!");
					var _u:Number=parseFloat(aItem[2]);
					var _v:Number=1-parseFloat(aItem[3]);
					
					gi.aNumberUV.push(new NumberUV(_u,_v));
					
				break;
				case "f"://每个三角面的信息,f 始终是3个的。"f -19/-46 -17/-45 -18/-44"
					//T.p("这个是f!!");
					//part 1:顶点索引.-1是因为他是从1开始的
					var a:int=verticesCount+parseInt((aItem[1].split("/"))[0]);//-verticesCount;
					var b:int=verticesCount+parseInt((aItem[2].split("/"))[0]);//-verticesCount;
					var c:int=verticesCount+parseInt((aItem[3].split("/"))[0]);//-verticesCount;
					
					//part 2:真正的各个面的纹理,这些是索引
					var at:int=textureVerticesCount+parseInt((aItem[1].split("/"))[1]);//-textureVerticesCount;
					var bt:int=textureVerticesCount+parseInt((aItem[2].split("/"))[1]);//-textureVerticesCount;
					var ct:int=textureVerticesCount+parseInt((aItem[3].split("/"))[1]);//-textureVerticesCount;
					
					//T.p("!22",a,b,c);
					//T.p("!33",at,bt,ct);
					
					gi.aFace.push(new Face3D(gi,a,b,c,at,bt,ct));
					
				break;
			}
		}
		//
		//T.p("--------------解析完毕----------------");
		//ttt("顶点",aVB_p);
		//ttt("文理",aVB_t);
		//ttt("三角条顶点索引",a2IB_p);
		//ttt("三角条纹理索引",a2IB_t);

		//-----生成mesh
		var mesh:Mesh3D=new Mesh3D();
		mesh.name=name;
		
		mesh.setGeometryInfo(gi);

		return mesh;
	}
}
}
